﻿using IdentityModel;
using Microsoft.IdentityModel.Tokens;
using Mysoft.Common.Configuration;
using Mysoft.Common.Extensions;
using Mysoft.Common.Model;
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;

namespace Mysoft.Common.Jwt
{
    public class JwtHelper
    {

        /// <summary>
        /// 生成JWT
        /// </summary>
        /// <param name="serInfo"></param>
        /// <returns></returns>
        public static string IssueJwt(UserInfo user)
        {
            var tokenHandler = new JwtSecurityTokenHandler();
            var authTime = DateTime.Now;
            var expiresAt = authTime.AddMinutes(AppSetting.JWTToken.AccessExpiration);//到期时间
            var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(AppSetting.JWTToken.Secret));
            var tokenDescriptor = new SecurityTokenDescriptor
            {
                Subject = new ClaimsIdentity(new Claim[]
                {
                        new Claim(JwtRegisteredClaimNames.Jti,user.Id.ToString()),
                        new Claim(JwtRegisteredClaimNames.Iat, $"{new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds()}"),
                        new Claim(JwtRegisteredClaimNames.Nbf,$"{new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds()}") ,


                        new Claim(JwtRegisteredClaimNames.Iss,AppSetting.JWTToken.Issuer),
                        new Claim(JwtRegisteredClaimNames.Aud,AppSetting.JWTToken.Audience),

                        new Claim(JwtClaimTypes.NotBefore, $"{new DateTimeOffset(authTime).ToUnixTimeSeconds()}"),//token生效时间
                        new Claim(JwtClaimTypes.Expiration, $"{new DateTimeOffset(expiresAt).ToUnixTimeSeconds()}")//到期时间，按秒数计算
                }),
                IssuedAt = DateTime.Now,//token生成时间
                Expires = expiresAt,
                NotBefore = authTime,
                SigningCredentials = new SigningCredentials(key, SecurityAlgorithms.HmacSha256Signature)//密钥和加密方式
            };
            var jwtToken = tokenHandler.CreateToken(tokenDescriptor);
            var token = tokenHandler.WriteToken(jwtToken);
            return token;
        }

        /// <summary>
        /// 解析
        /// </summary>
        /// <param name="jwtStr"></param>
        /// <returns></returns>
        public static UserInfo SerializeJwt(string jwtStr)
        {
            var jwtHandler = new JwtSecurityTokenHandler();
            JwtSecurityToken jwtToken = jwtHandler.ReadJwtToken(jwtStr);
            UserInfo userInfo = new UserInfo
            {
                Id = Guid.Parse(jwtToken.Id),
                Name = jwtToken.Payload[ClaimTypes.Name]?.ToString()
            };
            return userInfo;
        }
        /// <summary>
        /// 获取过期时间
        /// </summary>
        /// <param name="jwtStr"></param>
        /// <returns></returns>
        public static DateTime GetExp(string jwtStr)
        {
            var jwtHandler = new JwtSecurityTokenHandler();
            JwtSecurityToken jwtToken = jwtHandler.ReadJwtToken(jwtStr);

            DateTime expDate = (jwtToken.Payload[JwtRegisteredClaimNames.Exp] ?? 0).GetLong().GetTimeSpmpToDate();
            return expDate;
        }
        public static bool IsExp(string jwtStr)
        {
            return GetExp(jwtStr) < DateTime.Now;
        }

        public static Guid? GetUserId(string jwtStr)
        {
            try
            {
                return new JwtSecurityTokenHandler().ReadJwtToken(jwtStr).Id.GetGuid();
            }
            catch
            {
                return Guid.Empty;
            }
        }
    }
}
